package com.heima.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.config.MinioProp;
import com.heima.mapper.MaterialMapper;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmMaterialDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.service.MaterialService;
import com.heima.utils.MinioUtils;
import com.heima.utils.WMThreadLocal;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author chenshan
 */
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, WmMaterial>
        implements MaterialService {

    @Autowired
    private MinioUtils minioUtils;

    @Autowired
    private MinioProp prop;

    /**
     * 自媒体端文件上传
     * @param multipartFile 文件
     * @return ResponseResult
     */
    @Override
    public ResponseResult uploadPicture(MultipartFile multipartFile) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ServerException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InsufficientDataException, InternalException {
        // 校验文件是否为空
        if (ObjectUtil.isNull(multipartFile)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 校验文件格式
        String originalFilename = multipartFile.getOriginalFilename();
        String extName = FileUtil.extName(originalFilename);
        if (!StrUtil.containsAny(extName, "jpg", "png")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_IMAGE_FORMAT_ERROR);
        }

        // 校验图片的大小
        if (multipartFile.getSize() / 1024 / 1024 > 2) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "图片大小不能超过2M");
        }

        // 给图片重命名
        String newFileName = UUID.randomUUID().toString() + "." + FileUtil.extName(originalFilename);
        // 根据日期做目录分离
        String dateTime = DateTime.now().toString("yyyy/MM/dd");
        String fileName = dateTime + "/" + newFileName;

        minioUtils.putObject(prop.getBucket(), multipartFile, fileName, multipartFile.getContentType());

        // 拼凑url
        String url = minioUtils.getBasisUrl() + fileName;

        // 把这个数据存储到数据库中
        WmMaterial material = new WmMaterial();
        material.setUserId(WMThreadLocal.get());
        material.setUrl(url);
        material.setType((short) 0);
        material.setIsCollection((short) 0);
        material.setCreatedTime(new DateTime());
        save(material);

        return ResponseResult.okResult(material);
    }

    /**
     * 当前登录用户的素材的分页查询
     * @param materialDto 是否收藏和分页条件
     * @return ResponseResult 分页结果
     */
    @Override
    public PageResponseResult materialList(WmMaterialDto materialDto) {
        // 校验分页参数
        materialDto.checkParam();

        // 分页查询
        Page<WmMaterial> page = new Page<>(materialDto.getPage(), materialDto.getSize());
        page(page, Wrappers.lambdaQuery(WmMaterial.class)
                .eq(ObjectUtil.isNotNull(materialDto.getIsCollection()), WmMaterial::getIsCollection, materialDto.getIsCollection())
                .eq(ObjectUtil.isNotNull(WMThreadLocal.get()), WmMaterial::getUserId, WMThreadLocal.get()));

        // 封装返回值
        PageResponseResult result = new PageResponseResult(Convert.toInt(page.getCurrent()), Convert.toInt(page.getSize()), Convert.toInt(page.getTotal()));
        result.setData(page.getRecords());

        return result;
    }
}




